
package myPackage;

import java.awt.Color;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JTextArea;
//import JXTA libraries
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.StringMessageElement;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.OutputPipeEvent;
import net.jxta.pipe.OutputPipeListener;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.rendezvous.RendezVousService;
import net.jxta.rendezvous.RendezvousEvent;
import net.jxta.rendezvous.RendezvousListener;

//This class will send messages thro pipe for chatting services
public class ChatOutput extends Thread implements Runnable,
                                                  OutputPipeListener,
                                                  RendezvousListener
{   //Class Variables
    private JTextArea log=null , txtChat =null;
    private String myPeerID = null,
                   myPeerName= null;
    private PeerGroup rootGroup =null;
    private PipeService myPipeService = null;
    
    private OutputPipe pipeOut =null;
    private PipeAdvertisement pipeAdv=null;
    private DiscoveryService myDiscoveryService=null;
    
    private RendezVousService myRendezVousService=null;
    private String msg = null;
    private boolean Locationflag = false;
    private boolean Roleflag = false;
    private Message roleMsg = null;
    private Message locationMsg = null;
    private String loc = null;
    /** Creates a new instance of ChatOutput */
    public ChatOutput(PeerGroup group,JTextArea log,JTextArea chat) 
    {
        this.log = log;
        this.txtChat = chat;
        this.rootGroup=group;        
        getServices();
        
    }
    private void getServices() //This method will obtain Peer Group Services
    {
        log.append("[+]Obtaining Services for chat...\n");
        try{
            myRendezVousService = rootGroup.getRendezVousService();
            myRendezVousService.addListener(this);
            
        }catch(Exception e){
            System.out.println("[-]Cannot obtain RendezVous Services.");
            System.out.println("[-]Fatal Error: " + e.getMessage());
            e.printStackTrace();
            System.exit(-1);
        }
        myDiscoveryService = rootGroup.getDiscoveryService();
        myPipeService = rootGroup.getPipeService();
        myPeerID = rootGroup.getPeerID().toString();
        myPeerName = rootGroup.getPeerName();
        
        try{//Creating Pipe Advertisements from file
            FileInputStream in = new FileInputStream("saeedPipe.adv");
            pipeAdv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8,in);
            in.close();
        }catch(IOException e){
            System.out.println("[-]Exception: " + e.getMessage());
            e.printStackTrace();
            System.exit(-1);
        }
        log.append("[+]Chat Services sucessfully obtained.\n");
        
    }
    public void startingPipe()
    {
        log.append("[+]Creating Output Pipe.\n");
        try{
            //starting remoted advertisement to search for pipe
            myDiscoveryService.getRemoteAdvertisements(null,DiscoveryService.ADV,null,null,1);
            myPipeService.createOutputPipe(pipeAdv,this);
        }catch(Exception e){
            log.append("[+]Exception: " + e.getMessage()+"\n");
            e.printStackTrace();
            System.exit(-1);
        }
        log.append("[+]Output Pipe Successfully Created.\n");
    }
    
    public void setMessage(String message){//This accessor will set messages that need to be sent
        this.msg = message;
    } 
    
    public void createLocationInfoMsg(String to,String location){
    	Locationflag = true;
    	loc = location;
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        String myTime = dateFormat.format(date).toString();
        String type = "Location";
        locationMsg = new Message();
        
        //adding timestap and peers details also messages to XML tag and send them 
        StringMessageElement sme = new StringMessageElement("Type",type,null);
        StringMessageElement sme1 = new StringMessageElement("PeerName",myPeerName,null);
        StringMessageElement sme2 = new StringMessageElement("Receiver",to,null);
        StringMessageElement sme3 = new StringMessageElement("Location",loc,null);
        StringMessageElement sme4 = new StringMessageElement("Time",myTime,null);
        
        
        locationMsg.addMessageElement(null,sme);
        locationMsg.addMessageElement(null,sme1);
        locationMsg.addMessageElement(null,sme2);
        locationMsg.addMessageElement(null,sme3);
        locationMsg.addMessageElement(null,sme4);
    }
    
    public void createRoleInfoMsg(String peername, String rolename){
    	Roleflag = true;
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        String myTime = dateFormat.format(date).toString();
        
        String type = "role_name";
        roleMsg = new Message();
        
        StringMessageElement sme = new StringMessageElement("Type",type,null);
        StringMessageElement sme1 = new StringMessageElement("PeerName",myPeerName,null);
        StringMessageElement sme2 = new StringMessageElement("Receiver",peername,null);
        StringMessageElement sme3 = new StringMessageElement("Role_Name",rolename,null);
        StringMessageElement sme4 = new StringMessageElement("Time",myTime,null);
        
        
        roleMsg.addMessageElement(null,sme);
        roleMsg.addMessageElement(null,sme1);
        roleMsg.addMessageElement(null,sme2);
        roleMsg.addMessageElement(null,sme3);
        roleMsg.addMessageElement(null,sme4);
    }
    
    public void stopSending() //This method will stop input pipe
    {
    	pipeOut.close();
        log.append("[-]Input Pipe Closed for Incomming Message.\n");
    }
    
    //Listener to send message thro pipe as requested        
    public void outputPipeEvent(OutputPipeEvent ev)
    {
        log.append("[+]Sending Message.\n");
        pipeOut = ev.getOutputPipe();
        Message myMessage = null;
        
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        String myTime = dateFormat.format(date).toString();
        if(!Locationflag&&!Roleflag)
        try{
            
            myMessage = new Message();
            //adding timestap and peers details also messages to XML tag and send them 
            StringMessageElement sme = new StringMessageElement("Type","Chat",null);
            StringMessageElement sme1 = new StringMessageElement("peerName",myPeerName,null);
            StringMessageElement sme2 = new StringMessageElement("peerID",myPeerID,null);
            StringMessageElement sme3 = new StringMessageElement("chatMessage",msg,null);
            StringMessageElement sme4 = new StringMessageElement("Time",myTime,null);
            
            myMessage.addMessageElement(null,sme);
            myMessage.addMessageElement(null,sme1);
            myMessage.addMessageElement(null,sme2);
            myMessage.addMessageElement(null,sme3);
            myMessage.addMessageElement(null,sme4);
            //Trigger the Sending            
            pipeOut.send(myMessage);
            txtChat.append("[ " + myPeerName+"@" + myTime+ "]  " + msg + "\n");
            
        }catch(Exception e)
        {
            log.append("[-]Exception: " + e.getMessage()+"\n");
            e.printStackTrace();
            System.exit(-1);            
        }
        else if (Locationflag){
        try{
        	pipeOut.send(locationMsg);
        	System.out.println("Location infomation Send");
        	Locationflag = false;
        }catch(Exception e)
        {
            log.append("[-]Exception: " + e.getMessage()+"\n");
            e.printStackTrace();
            System.exit(-1);            
        }	
        }
        else if(Roleflag){
        	try{
        		pipeOut.send(roleMsg);
        		Roleflag = false;
        	}catch(Exception e)
            {
                log.append("[-]Exception: " + e.getMessage()+"\n");
                e.printStackTrace();
                System.exit(-1);            
            }	
        }
        
    }
    
    public synchronized void rendezvousEvent(RendezvousEvent event) 
    {
        if(event.getType() == event.RDVCONNECT || event.getType() == event.RDVRECONNECT){
            notify();
        }
    }
}
